package cn.sjj.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 对文件和文件夹的操作的支持类
 * 
 * @author 宋疆疆
 * 
 */
public class FileUtil {

	// 循环遍历指定目录里的文件和文件夹
	private void lsFiles(String path) {
		File dir = new File(path);
		if (dir.exists()) {
			File[] listFiles = dir.listFiles();
			for (File file : listFiles) {
				if (file.isDirectory()) {
					System.out.println("dir: " + file.getName());
				}
				if (file.isFile()) {
					System.out.println("file: " + file.getName());
				}
			}
		}
	}

	// 复制文件夹
	public static void copyDirectiory(String sourceDir, String targetDir)
			throws IOException {
		// 新建目标目录
		(new File(targetDir)).mkdirs();
		// 获取源文件夹当前下的文件或目录
		File[] file = (new File(sourceDir)).listFiles();
		for (int i = 0; i < file.length; i++) {
			if (file[i].isFile()) {
				// 源文件
				File sourceFile = file[i];
				// 目标文件
				File targetFile = new File(
						new File(targetDir).getAbsolutePath() + File.separator
								+ file[i].getName());
				copyFile(sourceFile, targetFile);
			}
			if (file[i].isDirectory()) {
				// 准备复制的源文件夹
				String dir1 = sourceDir + "/" + file[i].getName();
				// 准备复制的目标文件夹
				String dir2 = targetDir + "/" + file[i].getName();
				copyDirectiory(dir1, dir2);
			}
		}
	}

	// 复制文件
	public static void copyFile(File sourceFile, File targetFile)
			throws IOException {
		BufferedInputStream inBuff = null;
		BufferedOutputStream outBuff = null;
		try {
			// 新建文件输入流并对它进行缓冲
			inBuff = new BufferedInputStream(new FileInputStream(sourceFile));

			// 新建文件输出流并对它进行缓冲
			outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));

			// 缓冲数组
			byte[] b = new byte[1024 * 5];
			int len;
			while ((len = inBuff.read(b)) != -1) {
				outBuff.write(b, 0, len);
			}
			// 刷新此缓冲的输出流
			outBuff.flush();
		} finally {
			// 关闭流
			if (inBuff != null)
				inBuff.close();
			if (outBuff != null)
				outBuff.close();
		}
	}

	// 验证字符串是否为正确路径名的正则表达式
	private static String matches = "[A-Za-z]:\\\\[^:?\"><*]*";

	// 通过 sPath.matches(matches) 方法的返回值判断是否正确
	// sPath 为路径字符串
	/**
	 * 根据路径删除指定的目录或文件，无论存在与否
	 * 
	 * @param sPath
	 *            要删除的目录或文件
	 * @return 删除成功返回 true，否则返回 false。
	 */
	public static boolean DeleteFolder(String sPath) {
		boolean flag = false;
		File file = new File(sPath);
		// 判断目录或文件是否存在
		if (!file.exists()) { // 不存在返回 false
			return flag;
		} else {
			// 判断是否为文件
			if (file.isFile()) { // 为文件时调用删除文件方法
				return deleteFile(sPath);
			} else { // 为目录时调用删除目录方法
				return deleteDirectory(sPath);
			}
		}
	}

	/**
	 * 删除单个文件
	 * 
	 * @param sPath
	 *            被删除文件的文件名
	 * @return 单个文件删除成功返回true，否则返回false
	 */
	public static boolean deleteFile(String sPath) {
		boolean flag = false;
		File file = new File(sPath);
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists()) {
			file.delete();
			flag = true;
		}
		return flag;
	}

	/**
	 * 删除目录（文件夹）以及目录下的文件
	 * 
	 * @param sPath
	 *            被删除目录的文件路径
	 * @return 目录删除成功返回true，否则返回false
	 */
	public static boolean deleteDirectory(String sPath) {
		// 如果sPath不以文件分隔符结尾，自动添加文件分隔符
		if (!sPath.endsWith(File.separator)) {
			sPath = sPath + File.separator;
		}
		File dirFile = new File(sPath);
		// 如果dir对应的文件不存在，或者不是一个目录，则退出
		if (!dirFile.exists() || !dirFile.isDirectory()) {
			return false;
		}
		boolean flag = true;
		// 删除文件夹下的所有文件(包括子目录)
		File[] files = dirFile.listFiles();
		for (int i = 0; i < files.length; i++) {
			// 删除子文件
			if (files[i].isFile()) {
				flag = deleteFile(files[i].getAbsolutePath());
				if (!flag)
					break;
			} // 删除子目录
			else {
				flag = deleteDirectory(files[i].getAbsolutePath());
				if (!flag)
					break;
			}
		}
		if (!flag)
			return false;
		// 删除当前目录
		if (dirFile.delete()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 创建文件夹，赋予所有人需要的权限
	 * 
	 * @param path
	 * @param readable
	 * @param writable
	 * @param executable
	 * @return
	 */
	public static boolean createDirectory(String path, boolean readable,
			boolean writable, boolean executable) {
		File dir = new File(path);
		boolean isSuccess = false;
		if (!dir.exists()) {
			isSuccess = dir.mkdirs();
			if (readable) {
				isSuccess = dir.setReadable(true, false);
			}
			if (writable) {
				isSuccess = dir.setWritable(true, false);
			}
			if (executable) {
				isSuccess = dir.setExecutable(true, false);
			}
		} else {
			return dir.canExecute() & dir.canRead() & dir.canWrite();
		}
		return isSuccess;
	}

	/**
	 * 创建文件，赋予所有人需要的权限
	 * 
	 * @param path
	 * @param readable
	 * @param writable
	 * @param executable
	 * @return
	 */
	public static boolean createFile(String path, boolean readable,
			boolean writable, boolean executable) throws IOException {
		boolean isSuccess = false;
		File file = new File(path);
		File parentFile = file.getParentFile();
		if (!parentFile.exists()) {
			isSuccess = createDirectory(parentFile.getAbsolutePath(), readable,
					writable, executable);
		}
		if (!file.exists()) {
			isSuccess = file.createNewFile();
			if (readable) {
				isSuccess = file.setReadable(true, false);
			}
			if (writable) {
				isSuccess = file.setWritable(true, false);
			}
			if (executable) {
				isSuccess = file.setExecutable(true, false);
			}
		} else {
			return file.canExecute() & file.canRead() & file.canWrite();
		}
		return isSuccess;
	}

	/**
	 * 重命名文件名字
	 * 
	 * @param oldPath
	 * @param newPath
	 * @return true 重命名成功
	 */
	public static boolean rename(String oldPath, String newPath) {
		File file = new File(oldPath);
		if (file.exists()) {
			File dest = new File(newPath);
			return file.renameTo(dest);
		}
		return false;
	}
}
